package com.hisense.ovcloud.asop.dao;

import com.hisense.ovcloud.asop.config.Constants;
import com.hisense.ovcloud.asop.dto.req.PublicInfoReq;
import com.hisense.ovcloud.asop.entity.db.CustomDevicePair;
import com.hisense.ovcloud.asop.mapper.CustomDevicePairMapper;
import com.mybatisflex.annotation.UseDataSource;
import com.mybatisflex.core.query.QueryWrapper;
import io.micrometer.common.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

import static com.hisense.ovcloud.asop.entity.db.def.CustomDevicePairTableDef.CUSTOM_DEVICE_PAIR;

@Service
@Slf4j
public class CustomDevicePairDao {
    private final LocalDateTime dateToCompareForPairEnd = LocalDateTime.parse("2088-08-22 22:22:22", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    final
    CustomDevicePairMapper customDevicePairMapper;

    public CustomDevicePairDao(CustomDevicePairMapper customDevicePairMapper) {
        this.customDevicePairMapper = customDevicePairMapper;
    }

    private QueryWrapper createQueryWrapperForWifiUpgradeResults(List<String> wifiIdList, List<String> customerIdList, PublicInfoReq r){
        QueryWrapper q = new QueryWrapper()
                .select(CUSTOM_DEVICE_PAIR.ALL_COLUMNS)
                .from(CUSTOM_DEVICE_PAIR)
                .orderBy(CUSTOM_DEVICE_PAIR.PAIR_BEGIN, false);
        if(!customerIdList.isEmpty()){
            q = q.and(CUSTOM_DEVICE_PAIR.CUSTOMER_ID.in(customerIdList));
        }
        if(!wifiIdList.isEmpty()){
            q = q.and(CUSTOM_DEVICE_PAIR.WIFI_ID.in(wifiIdList));
        }
        if(StringUtils.isNotEmpty(r.getWifiId())){
            q = q.and(CUSTOM_DEVICE_PAIR.WIFI_ID.eq(r.getWifiId()));
        }
        if(StringUtils.isNotEmpty(r.getPuid())){
            q = q.and(CUSTOM_DEVICE_PAIR.PUID.eq(r.getPuid()));
        }
        if(StringUtils.isNotEmpty(r.getDeviceId())){
            q = q.and(CUSTOM_DEVICE_PAIR.DEVICE_ID.eq(r.getDeviceId()));
        }

        if(r.getStartTime() > 0){
            q = q.and(CUSTOM_DEVICE_PAIR.PAIR_BEGIN.gt(r.getStartTime()));
        }
        if(r.getEndTime() > 0){
            q = q.and(CUSTOM_DEVICE_PAIR.CUSTOMER_ID.lt(r.getEndTime()));
        }

        return q;
    }

    @UseDataSource(Constants.DS.BIGDATA)
    public List<CustomDevicePair> fetchBindHistory(List<String> wifiIdList, List<String> customerIdList, PublicInfoReq r){
        QueryWrapper q = createQueryWrapperForWifiUpgradeResults(wifiIdList, customerIdList, r);
        q = q.limit((r.getPageNum()-1) * r.getPageSize(), r.getPageSize());
        return customDevicePairMapper.selectListByQueryAs(
                q,
                CustomDevicePair.class).stream().map(this::transDateToUTC).collect(Collectors.toList());
    }

    private CustomDevicePair transDateToUTC(CustomDevicePair cdr){
        try{
            if(StringUtils.isNotEmpty(cdr.getTimezoneId())){
                if(null != cdr.getPairBegin()){
                    cdr.setPairBegin(new Timestamp(cdr.getPairBegin().toLocalDateTime().atZone(ZoneId.of(cdr.getTimezoneId())).toInstant().toEpochMilli()));
                }
                if(null != cdr.getPairEnd() && cdr.getPairEnd().toLocalDateTime().isBefore(dateToCompareForPairEnd)){
                    cdr.setPairEnd(new Timestamp(cdr.getPairEnd().toLocalDateTime().atZone(ZoneId.of(cdr.getTimezoneId())).toInstant().toEpochMilli()));
                }
            }
        }catch (Exception e){
            log.error("failed to transfer pairBegin/pairEnd to UTC time: {}", e.getMessage());
        }

        return cdr;
    }

    @UseDataSource(Constants.DS.BIGDATA)
    public long fetchBindHistoryTotal(List<String> wifiIdList, List<String> customerIdList, PublicInfoReq r){
        QueryWrapper q = createQueryWrapperForWifiUpgradeResults(wifiIdList, customerIdList, r);
        return customDevicePairMapper.selectCountByQuery(
                q);
    }
}
